#include <iostream>
#include <iostream>
#include <numeric>
#include <ranges>
#include "fmt/format.h"
using namespace std;

int main()
{
    auto showValues{
        [](auto &values, const std::string &message)
        {
            std::cout << fmt::format("{}: ", message);
            for (const auto &value : values)
            {
                std::cout << fmt::format("{} ", value);
            }
            cout << "\n";
        }};

    auto values1{std::views::iota(1, 11)};
    showValues(values1, "Generate intergers 1-10");

    auto values2{values1 | std::views::filter([](const auto &x)
                                              { return x % 2 == 0; })};
    showValues(values2, "Filtering even integers");

    auto values3{values2 | std::views::transform([](const auto &x)
                                                 { return x * x; })};
    showValues(values3, "Mapping even intergers to squares");

    auto values4{values1 | std::views::filter([](const auto &x)
                                              { return x % 2 == 0; }) |
                 std::views::transform([](const auto &x)
                                       { return x * x; })};
    showValues(values4, "filter even intergers and squares");

    constexpr std::array numbers{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    auto values5{numbers | std::views::filter([](const auto &x)
                                              { return x % 2 == 0; }) |
                 std::views::transform([](const auto &x)
                                       { return x * x; })};
    showValues(values5, "filter even intergers and squares from an array");

    string s{"123.546hello"};
    double convertedDouble{stod(s)};
    cout << "double:" << convertedDouble << "\n";
    return 0;
}
